home *** CD-ROM | disk | FTP | other *** search
- Subject: v20i023: Deliver, flexible email delivery system, Part01/04
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Chip Salzenberg <chip@ateng.com>
- Posting-number: Volume 20, Issue 23
- Archive-name: deliver2.0/part01
-
- Deliver is a program which delivers electronic mail once it has arrived
- at a given machine. It is intended for use in three environments:
- 1. Any Xenix system.
- 2. Any Unix system with smail 2.x.
- 3. Any Unix system with either sendmail or smail 3.x.
-
- If you have been frustrated by inflexible E-Mail delivery, here is your
- salvation. Deliver permits complete control over mail delivery through
- the use of "delivery files." Delivery files are shell scripts which are
- executed during message delivery. These shell scripts -- written by you!
- -- control who, if anyone, gets each E-Mail message.
-
- Mostly, Deliver 2.0 is an incremental enhancement from Deliver 1.0.8. New
- features include:
- 1. Parsing of the From_ line. Badly formed From_ lines, including
- those with illegal dates, are rejected. Messages with invalid From_
- lines are still delivered, but the contents the From_ line is
- put into an Invalid-UUCP-From: line.
-
- 2. The "header" program, which parses RFC822 headers. Besides its
- obvious utility in delivery files, header should prove quite useful
- for scanning Usenet directories.
-
- 3. Sample delivery files, including the often-requested vacation
- "answering machine".
-
- --
- Chip Salzenberg <chip@ateng.com> or <uunet!ateng!chip>
- A T Engineering "Designed with your mind in mind."
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: README deliver.8 Makefile uid.c header.c getopt.c samples
- # samples/README samples/p-aliases samples/s-aliases samples/u-chip
- # samples/u-vacation
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(2335 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X$Header: README,v 2.1 89/06/09 12:25:10 network Exp $
- X
- X
- X WHAT IS DELIVER?
- X
- X
- XDeliver is a program which delivers electronic mail once it has arrived
- Xat a given machine.
- X
- X
- X
- X WHO CAN USE IT?
- X
- X
- XDeliver is intended for use in three environments:
- X
- X
- X 1. Any Xenix system.
- X
- X Deliver was invented to be a direct replacement for the Xenix
- X program /usr/lib/mail/mail.local. In fact, on ateng, mail.local is
- X just another link to /usr/bin/deliver.
- X
- X
- X 2. Any Unix system with smail 2.x.
- X
- X You can use deliver for local mail by changing the local mailer
- X definition in config.h:
- X #define LMAIL(frm) "/usr/bin/deliver -r '%s'",frm
- X
- X
- X 3. Any Unix system with either sendmail or smail 3.x.
- X
- X Any user can let deliver handle all his mail by putting the
- X following line in his .forward file:
- X "|/usr/bin/deliver username"
- X Be sure to specify the correct username, or someone else will
- X get your mail!
- X
- X
- X
- X PORTABILITY
- X
- X
- XDeliver has been compiled and tested under SCO Xenix System V/286 and 4.3
- XBSD. The configuration provides for System V, but I have not been able to
- Xtest it. (Patches for all environments are welcome; see below.)
- X
- X
- X
- X WARNINGS: BE CAREFUL!
- X
- X
- X 1. Deliver is intended to be run setuid root; otherwise it would not
- X be possible to execute a user delivery file in the context of its
- X owner. Any setuid root program is a potential security hole! Be
- X careful of the modes on the deliver binary and the directory where
- X it lives.
- X
- X 2. Deliver's flexibility makes it easy to lose lots of mail through
- X carelessness in configuration. Delivery files should be written
- X with extreme care.
- X
- X
- X
- X COMPILING AND INSTALLING
- X
- X
- XEdit the Makefile and config.h to taste. Type "make". To install, type
- X"make install". See the Makefile for further hints.
- X
- X
- X
- X HELP SAVE THE WORLD!
- X
- X
- XIf you run into a bug, you are probably not alone. Save your fellow human
- Xbeings from toil and trouble! Send mail to <bugs-deliver@ateng.uucp>. Bug
- Xreports accepted; patches greatly appreciated. I will coordinate patches.
- X
- XThank you, and good night.
- X
- X Chip Salzenberg
- X A T Engineering
- X
- X <chip@ateng.uucp> or
- X <chip@ateng.uu.net> or
- X <uunet!ateng!chip>
- END_OF_FILE
- if test 2335 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'deliver.8' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'deliver.8'\"
- else
- echo shar: Extracting \"'deliver.8'\" \(11359 characters\)
- sed "s/^X//" >'deliver.8' <<'END_OF_FILE'
- X.\" $Header: deliver.8,v 2.1 89/06/09 12:25:19 network Exp $
- X.\"
- X.\" Man page for deliver.
- X.\"
- X.\" $Log: deliver.8,v $
- X.\" Revision 2.1 89/06/09 12:25:19 network
- X.\" Update RCS revisions.
- X.\"
- X.\" Revision 1.8 89/06/09 12:23:42 network
- X.\" Baseline for 2.0 release.
- X.\"
- X.TH DELIVER 8
- X.SH NAME
- Xdeliver \- deliver local mail
- X.SH SYNOPSIS
- X.B deliver
- X[ options ] address ...
- X.SH DESCRIPTION
- XThe
- X.I deliver
- Xprogram collects a mail message from the standard input and delivers it.
- XIt is intended to take over the delivery of all local mail, a job usually
- Xhandled by
- X.I /bin/mail
- X(System V),
- X.I /usr/lib/sendmail
- X(BSD), or
- X.I /usr/lib/mail/mail.local
- X(Xenix).
- X.PP
- X.I deliver
- Xintroduces flexibility in the handling of local mail delivery. All files
- Xused to control
- X.I deliver
- Xare Bourne shell scripts. Thus anything that can be called by a shell
- Xscript can be used to control mail delivery.
- X.SH OPTIONS
- X.TP
- X.B \-b
- XInterpret all arguments as mailbox filenames instead of addresses. Note
- Xthat the user running
- X.I deliver
- Xmust have write permissions on the given mailbox files. He may also need
- Xwrite permissions on their parent directories, depending on the existence
- Xof the mailbox file and the local locking protocol.
- X.TP
- X.B \-n
- XInterpret arguments as addresses, but do not run any delivery files; simply
- Xdeliver the message to the mailbox(es) of the given user(s). This option is
- Xmost useful when
- X.I deliver
- Xis executed recursively, since it prevents further recursion.
- X.TP
- X.B \-A
- XPrint resolved addresses; do not deliver the message. Note that
- X.I deliver
- Xstill collects a message from the standard input, since delivery files may
- Xdo different things depending on message content. For simple testing,
- Xredirect standard input from /dev/null.
- X.TP
- X.B \-d
- XBe verbose; don't deliver to any mailboxes or catch any signals.
- X.TP
- X.B \-v
- XBe verbose, but still deliver.
- X.TP
- X.B \-t
- XDo not remove temporary files before exiting.
- X.TP
- X.BI \-r " sender"
- XPut
- X.I sender
- Xon the generated From_ line. Default is to use the address on the From_
- Xline in the input, or else the name corresponding to the real uid, or else
- X"unknown".
- X.TP
- X.BI \-h " hostname"
- XSet the host name. The default is configuration dependent.
- X.TP
- X.BI \-s " system delivery file"
- XSpecify an alternate system delivery file. The default is
- X.I /usr/local/lib/deliver.sys.
- XFor security reasons, this option disables setuid privileges.
- X.TP
- X.BI \-p " post-user delivery file"
- XSpecify an alternate post-user delivery file. The default is
- X.I /usr/local/lib/deliver.post.
- XFor security reasons, this option disables setuid privileges.
- X.TP
- X.BI \-u " user delivery file"
- XSpecify an alternate user delivery file. The default is
- X.I .deliver
- X(in each user's home directory).
- XFor security reasons, this option disables setuid privileges.
- X.PP
- XAll command line options are put into environment variables, examined by
- X.I deliver
- Xon startup; thus all flags are propagated when
- X.I deliver
- Xis invoked recursively.
- X.SH ENVIRONMENT
- XFor mail systems based on
- X.I smail
- X2.x, the LMAIL (local mailer) macro can be changed to call
- X.I deliver.
- XFor mail systems based on
- X.I smail
- X3.x or
- X.I sendmail,
- Xa similar arrangement may be made; or individual users can invoke
- X.I deliver
- Xby mentioning it in their
- X.I .forward
- Xfiles.
- X.PP
- XFor Xenix systems,
- X.I deliver
- Xmay be used as a direct replacement for
- X.IR /usr/lib/mail/mail.local.
- X.PP
- XFor stock Unix systems, it may be possible to make
- X.I /bin/rmail
- Xa link to
- X.I deliver;
- Xhowever, this configuration has not been tested and is not recommended.
- XAny postmaster motivated enough to install
- X.I deliver,
- Xand who wants something better than the standard
- X.I /bin/rmail,
- Xshould install
- X.I smail.
- X.SH OPERATION
- XBy default,
- X.I deliver
- Xdeposits mail in the system mailbox for the named user(s). Also, as a
- Xnecessity for use with
- X.I smail
- X2.x,
- X.I deliver
- Xalso understands UUCP-style bang addresses well enough to forward the
- Xmessage correctly, using
- X.I uux.
- X.PP
- XHowever, this basic behavior only scratches the surface: the usefulness of
- X.I deliver
- Xderives from its flexibility; its behavior can be made to depend on the
- Xrecipient(s), content or any other aspect of mail messages.
- X.PP
- XWhen
- X.I deliver
- Xstarts execution, it interprets its arguments in one of three ways. If the
- X.B \-b
- X(mailbox) option was specified, then all arguments are interpreted as
- Xmailbox pathnames. Otherwise, if a system delivery file exists and the
- X.B \-n
- X(no delivery files) option was not specified,
- X.I deliver
- Xexecutes the system delivery file with all of deliver's arguments
- Xas its arguments.
- X.I deliver
- Xinterprets the delivery file's output as described below. This procedure
- Xgives the postmaster control over delivery to non-existent hosts and users.
- XIf the
- X.B \-n
- Xoption is specified or if there is no system delivery file,
- X.I deliver
- Xinterprets all its arguments as mail addresses.
- X.PP
- XAfter possibly executing the system delivery file,
- X.I deliver
- Xlooks in its list of destinations for valid user names without explicitly
- Xnamed mailboxes. If any of these users have user delivery files in
- Xtheir home directories, and if the
- X.B \-n
- Xoption was not specified,
- X.I deliver
- Xexecutes each user delivery file with the name of the given user as its
- Xonly argument.
- X.PP
- XAfter executing any user delivery files,
- X.I deliver
- Xlooks in its list of destinations for simple user names and UUCP
- Xaddresses. If any are found, if the post-user delivery file exists,
- Xand if the
- X.B \-n
- Xoption was not specified,
- X.I deliver
- Xexecutes the post-user delivery file with these addresses as its arguments.
- X.SH "DELIVERY FILES"
- XDelivery files are shell scripts. They are executed by
- X.I deliver
- Xto control delivery to users. Note that delivery files do
- X.I not
- Xcontrol delivery to explicitly named mailboxes.
- X.PP
- XOn each system the postmaster may create a
- X.I system delivery file
- Xto controls delivery of all messages.
- XThe system delivery file, if it exists, is executed
- Xwith the name(s) specified on the
- X.I deliver
- Xcommand line as its arguments.
- X.PP
- XThe postmaster may also create a
- X.I post-user delivery file
- Xwhich is executed after any user delivery files, but before delivery of the
- Xmessage to any mailboxes. This file is particularly useful for implementing
- Xsystem-wide aliases, since it can deal with addresses generated by user
- Xdelivery files, whereas the system delivery file cannot.
- X.PP
- XFinally, each user may create a
- X.I user delivery file
- Xin his home directory. User delivery files are always executed with exactly
- Xone argument: the name of the user in whose home directory the file is
- Xfound.
- X.PP
- XRecursive execution of
- X.I deliver
- Xis useful, especially with the
- X.B \-b
- X(mailbox) and
- X.B \-n
- X(no delivery files) flags. For example, a user may wish to transform a
- Xmessage body before it is stored in a mailbox. This may be done with a user
- Xdelivery file and recursive execution of
- X.I deliver.
- XFor example, the following user delivery file translates all incoming
- Xmessage bodies to lower case, and stores them in the user's default mailbox:
- X.TP
- X(cat $HEADER; tr '[A-Z]' '[a-z]' <$BODY) | deliver -n "$1"
- X.PP
- XWhen
- X.I deliver
- Xexecutes a delivery file, it sets several environment variables, listed
- Xbelow.
- XNote that these environment variables are both set and used by
- X.I deliver;
- Xtherefore, all command line options automatically propagate when
- X.I deliver
- Xis run recursively (within a delivery file). The environment variable
- Xnames set and used by
- X.I deliver
- Xare:
- X.TP
- X.B DELFLAGS
- XThe command line flags, if any, specified on the
- X.I deliver
- Xcommand line.
- X.TP
- X.B SYSDELFILE
- XThe system delivery filename.
- X.TP
- X.B POSTDELFILE
- XThe post-user delivery filename.
- X.TP
- X.B USERDELFILE
- XThe user delivery filename, relative to the home directory of each user.
- X.TP
- X.B HOSTNAME
- XThe local host name, either the real hostname or a name specified with the
- X.B \-h
- Xoption to
- X.I deliver.
- X.TP
- X.B SENDER
- XThe sender, either an address specified with
- X.B \-r
- Xoption to
- X.I deliver,
- Xor the address given in the From_ line of the message, or the user who
- Xinvoked
- X.I deliver.
- X.TP
- X.B HEADER
- XThe name of the temporary file containing the message header.
- X.TP
- X.B BODY
- XThe name of the temporary file containing the message body.
- X.PP
- X.I deliver
- Xmonitors the standard output of delivery files for lines of two forms:
- Xeither "user" or "user:mailbox". Those users whose names appear in the
- Xoutput of a delivery file will receive the message. If a mailbox name
- Xappears after the user name, then that mailbox receives the message. If a
- Xmailbox name is not specified, the user's default mailbox is used. (The
- Xdefault mailbox for a user is configuration-dependent.) If a mailbox is not
- Xan absolute pathname, it is interpreted relative to the home directory of
- Xthe named user.
- X.PP
- X.B NOTE 1:
- XWhen
- X.I deliver
- Xexecutes a delivery file, it expects that delivery file to explicitly name
- Xall users (and, optionally, mailboxes) where the message should be
- Xdelivered. If a delivery file does not name any users in its output, then
- Xthe message will not be delivered to anyone whose mail delivery is
- Xcontrolled by that delivery file.
- X.PP
- XTherefore, a user delivery file containing only "exit" will keep the given
- Xuser from receiving any mail. A system delivery file containing only "exit"
- Xwill cause
- X.B all
- Xmail to disappear. So be careful!
- X.PP
- X.B NOTE 2:
- XIf
- X.I deliver
- Xis setuid root -- which it should be for normal operation -- then the system
- Xdelivery file is executed as root. Be
- X.I "very careful"
- Xabout its permissions and its contents! Carelessness here can easily
- Xcreate a security problem.
- X.PP
- X.B NOTE 3:
- XAll user delivery files are executed in the context of the user in whose
- Xhome directory they reside. A user's "context" includes the uid, gid, and
- Xhome directory as specified in /etc/passwd.
- X.PP
- X.B NOTE 4:
- XFor security reasons, if a user's home directory is writable to the world,
- X.I deliver
- Xwill ignore any delivery file that might be found there.
- X.PP
- X.B NOTE 5:
- XFor security reasons,
- X.I deliver
- Xrejects lines of the form "user:mailbox" when generated by a user delivery
- Xfile unless they are output by the given user's delivery file. In other
- Xwords, no user can request writing a mailbox as another user.
- X.SH LOCKING
- XSeveral preprocessor labels may be defined during compilation to control
- Xthe method(s) used by
- X.I deliver
- Xto lock mailboxes. These labels are:
- X.RS
- X.PP
- X.B ML_DOTLOCK
- XLock on exclusive creation of the mailbox name with ".lock"
- Xappended. (Version 7 and early BSD mailers use this method.)
- X.PP
- X.B ML_DOTMLK
- XLock on exclusive creation of
- X.I /tmp/basename.mlk,
- Xwhere
- X.I basename
- Xis the last component of the mailbox pathname. (Xenix mailers use this
- Xmethod.)
- X.PP
- X.B ML_LOCKF
- XExclusively lock mailbox with lockf().
- X.PP
- X.B ML_FCNTL
- XExclusively lock mailbox with fcntl().
- X.PP
- X.B ML_LOCKING
- XExclusively lock mailbox with locking().
- X.PP
- X.RE
- XOne or both of ML_DOTLOCK and ML_DOTMLK may be specified. At most one of
- XML_LOCKF, ML_FCNTL or ML_LOCKING may be specified.
- X.SH FILES
- X/usr/local/lib/deliver.sys system delivery file
- X.br
- X/usr/local/lib/deliver.post post-user delivery file
- X.br
- X~user/.deliver user delivery file(s)
- X.br
- X/etc/systemid system name (Xenix only)
- X.SH SUPPORT
- XEnhancements, enhancement requests, trouble reports, etc., should be mailed
- Xto <bugs-deliver@ateng.com>; or for UUCP-only sites,
- X<uunet!ateng!bugs-deliver>.
- X.SH "SEE ALSO"
- X.IR mail (1),
- X.IR uux (1),
- X.IR smail (8),
- X.IR sendmail (8)
- END_OF_FILE
- if test 11359 -ne `wc -c <'deliver.8'`; then
- echo shar: \"'deliver.8'\" unpacked with wrong size!
- fi
- # end of 'deliver.8'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(4306 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X# $Header: Makefile,v 2.2 89/06/09 13:19:53 network Exp $
- X#
- X# Makefile for deliver
- X#
- X# +----------------+
- X# | Things to make |
- X# +----------------+
- X#
- X# deliver Compile and link the deliver program.
- X# header Compile and link the header program.
- X# install Install deliver and header. (You must be root.)
- X# lint Run lint on all sources, creating lint.out.
- X# shar Create distribution sharchives.
- X# clean Clean up.
- X# clobber Remove everything that can be regenerated.
- X#
- X# +---------------+
- X# | Configuration |
- X# +---------------+
- X#
- X# SHELL
- X# I don't have to tell you...
- X#
- X# COPY
- X# Your local copy program. SCO Xenix users may want to change this
- X# to "copy -m" which preserves file modification time.
- X#
- X# SHAR
- X# Your local sharchive generator.
- X#
- X# CFLAGS
- X# Compile-time flags to cc.
- X# For BSD systems, include "-DBSD".
- X# For USG (System III and System V) systems, include "-DUSG".
- X#
- X# LDFLAGS
- X# Link-time flags to cc. The -i flag creates pure (sharable) code.
- X#
- X# LIBS
- X# Depending on your environment, you may or may not need to link
- X# with "-lx". SCO Xenix System V needs it; Altos Xenix doesn't.
- X#
- X# BIN
- X# Target directory for installation; /usr/bin is recommended.
- X# You may use /usr/local/bin (or whatever), but you must be sure
- X# that the directory you choose is in your PATH during mail
- X# transmission and delivery.
- X#
- X# DELSHAR
- X# Basename of sharchives created by "make shar".
- X#
- X
- XSHELL = /bin/sh
- XCOPY = cp
- XSHAR = shar
- XCFLAGS = -O
- XLDFLAGS = -i
- XLIBS = -lx
- XBIN = /usr/bin
- XDELSHAR = deliver.sh
- X
- X#
- X# The files that make up the deliver distribution.
- X#
- X
- XDOCS = README deliver.8
- XMF = Makefile
- X
- XHDRS = config.h context.h deliver.h dest.h patchlevel.h misc.h
- X
- XDELSRC1 = context.c copymsg.c
- XDELSRC2 = debug.c dest.c dfile.c lock.c main.c
- XDELSRC3 = mbox.c procs.c subs.c sysdep.c unctime.y uucp.c
- XDELSRCS = $(DELSRC1) $(DELSRC2) $(DELSRC3)
- XUIDSRCS = uid.c
- XHDRSRCS = header.c
- XCOMSRCS = getopt.c
- XSAMPLES = samples samples/*
- X
- XDELOBJS = context.o copymsg.o debug.o dest.o dfile.o lock.o \
- X main.o mbox.o procs.o subs.o sysdep.o unctime.o uucp.o
- XUIDOBJS = uid.o
- XHDROBJS = header.o
- XCOMOBJS = getopt.o
- X
- X#
- X# For GNU Make. Sorry about the ugliness.
- X#
- X
- X.PHONY: all install lint shar clean clobber
- X
- X#
- X# The default target.
- X#
- X
- Xall: deliver header uid
- X
- X#
- X# "make clobber" implies "make clean".
- X#
- X
- Xclobber:: clean
- X
- X#
- X# How to install deliver and associated utilities.
- X#
- X
- Xinstall: deliver header uid
- X @if [ `./uid -uU | fgrep '(root)' | wc -l` -ne 2 ]; \
- X then \
- X echo "Sorry! You must be root to install deliver."; \
- X exit 1; \
- X fi
- X $(COPY) deliver $(BIN)/deliver
- X chgrp root $(BIN)/deliver
- X chown root $(BIN)/deliver
- X chmod 4711 $(BIN)/deliver
- X $(COPY) header $(BIN)/header
- X chmod 755 $(BIN)/header
- X
- X#
- X# How to compile and link the program.
- X#
- X
- Xdeliver: $(DELOBJS) $(COMOBJS)
- X $(CC) $(LDFLAGS) -o $@ $(DELOBJS) $(COMOBJS) $(LIBS)
- X$(DELOBJS): $(HDRS)
- X
- Xclean::
- X rm -f $(DELOBJS)
- Xclobber::
- X rm -f deliver
- X
- X#
- X# A header parsing program.
- X#
- X
- Xheader: $(HDRSRCS) $(COMOBJS)
- X $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(HDRSRCS) $(COMOBJS) $(LIBS)
- X rm -f $(HDROBJS)
- X
- Xclobber::
- X rm -f header
- X
- X#
- X# A little program to check on user and group id's.
- X# (I wish that the System V "id" program were available everywhere.)
- X#
- X
- Xuid: $(UIDSRCS) $(COMOBJS) config.h
- X $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(UIDSRCS) $(COMOBJS) $(LIBS)
- X rm -f $(UIDOBJS)
- X
- Xclobber::
- X rm -f uid
- X
- X#
- X# Common subroutines
- X#
- X
- X$(COMOBJS): config.h
- X
- Xclean::
- X rm -f $(COMOBJS)
- X
- X#
- X# Look for fuzz.
- X#
- X
- Xlint: deliver.lint uid.lint
- X
- Xdeliver.lint: $(HDRS) $(DELSRCS) $(COMSRCS)
- X lint $(DELSRCS) $(COMSRCS) -lc $(LIBS) >$@
- X
- Xuid.lint: config.h $(UIDSRCS) $(COMSRCS)
- X lint $(UIDSRCS) $(COMSRCS) -lc $(LIBS) >$@
- X
- Xclean::
- X rm -f *.lint
- X
- X#
- X# Make distribution sharchives.
- X#
- X
- Xshar: $(DELSHAR).01 $(DELSHAR).02 $(DELSHAR).03 $(DELSHAR).04
- X$(DELSHAR).01: $(DOCS) $(MF) $(UIDSRCS) $(HDRSRCS) $(COMSRCS) $(SAMPLES)
- X $(SHAR) >$@ $(DOCS) $(MF) $(UIDSRCS) $(HDRSRCS) $(COMSRCS) $(SAMPLES)
- X$(DELSHAR).02: $(HDRS) $(DELSRC1)
- X $(SHAR) >$@ $(HDRS) $(DELSRC1)
- X$(DELSHAR).03: $(DELSRC2)
- X $(SHAR) >$@ $(DELSRC2)
- X$(DELSHAR).04: $(DELSRC3)
- X $(SHAR) >$@ $(DELSRC3)
- X
- Xclobber::
- X rm -f $(DELSHAR).??
- END_OF_FILE
- if test 4306 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'uid.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'uid.c'\"
- else
- echo shar: Extracting \"'uid.c'\" \(2772 characters\)
- sed "s/^X//" >'uid.c' <<'END_OF_FILE'
- X/* $Header: uid.c,v 2.1 89/06/09 12:25:41 network Exp $
- X *
- X * I wish the System V "id" program were universally available; but it
- X * isn't, so I've written this replacement.
- X *
- X * usage: uid [-options]
- X *
- X * Default action is to print one line in the manner of "id":
- X * uid=201(chip) gid=50(group) euid=0(root) egid=0(root)
- X * (Note that the "euid" and "egid" entries are not output if they are
- X * the same as the "uid" and "gid" values.)
- X *
- X * If an option string is specified, it disables the normal behavior in
- X * favor of displaying id information, one per line, in the order that
- X * the options appear in the option string. Legal options are:
- X * u real uid
- X * g real gid
- X * U effective uid
- X * G effective gid
- X *
- X * NOTE: This program is not a paragon of good style.
- X * It's just something I needed for a Makefile.
- X *
- X * $Log: uid.c,v $
- X * Revision 2.1 89/06/09 12:25:41 network
- X * Update RCS revisions.
- X *
- X * Revision 1.3 89/06/09 12:24:00 network
- X * Baseline for 2.0 release.
- X *
- X */
- X
- X#include <stdio.h>
- X#include <pwd.h>
- X#include <grp.h>
- X#include "config.h"
- X
- X#ifdef NULL
- X#undef NULL
- X#endif
- X#define NULL 0
- X
- Xextern struct passwd *getpwuid();
- Xextern struct group *getgrgid();
- X
- Xchar *progname = "uid";
- X
- Xchar *uid_desc();
- Xchar *gid_desc();
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X int uid, gid, euid, egid;
- X int c, lines, errcount;
- X
- X uid = getuid();
- X gid = getgid();
- X euid = geteuid();
- X egid = getegid();
- X
- X errcount = 0;
- X lines = 0;
- X
- X while ((c = getopt(argc, argv, "ugUG")) != EOF)
- X {
- X switch (c)
- X {
- X case 'u':
- X (void) printf("%s\n", uid_desc(uid));
- X ++lines;
- X break;
- X
- X case 'g':
- X (void) printf("%s\n", gid_desc(gid));
- X ++lines;
- X break;
- X
- X case 'U':
- X (void) printf("%s\n", uid_desc(euid));
- X ++lines;
- X break;
- X
- X case 'G':
- X (void) printf("%s\n", gid_desc(egid));
- X ++lines;
- X break;
- X
- X case '?':
- X ++errcount;
- X break;
- X }
- X }
- X
- X if (errcount)
- X {
- X (void) fprintf(stderr, "usage: uid [-ugUG]\n");
- X exit(1);
- X }
- X
- X if (lines == 0)
- X {
- X (void) printf("uid=%s", uid_desc(uid));
- X (void) printf(" gid=%s", gid_desc(gid));
- X
- X if (euid != uid)
- X (void) printf(" euid=%s", uid_desc(euid));
- X if (egid != gid)
- X (void) printf(" egid=%s", gid_desc(egid));
- X
- X (void) printf("\n");
- X }
- X
- X exit(0);
- X /* NOTREACHED */
- X}
- X
- Xchar *
- Xuid_desc(uid)
- Xint uid;
- X{
- X struct passwd *pw;
- X static char buf[80];
- X
- X (void) sprintf(buf, "%d", uid);
- X if ((pw = getpwuid(uid)) != NULL)
- X (void) sprintf(buf + strlen(buf), "(%s)", pw->pw_name);
- X
- X return buf;
- X}
- X
- Xchar *
- Xgid_desc(gid)
- Xint gid;
- X{
- X struct group *gr;
- X static char buf[80];
- X
- X (void) sprintf(buf, "%d", gid);
- X if ((gr = getgrgid(gid)) != NULL)
- X (void) sprintf(buf + strlen(buf), "(%s)", gr->gr_name);
- X
- X return buf;
- X}
- END_OF_FILE
- if test 2772 -ne `wc -c <'uid.c'`; then
- echo shar: \"'uid.c'\" unpacked with wrong size!
- fi
- # end of 'uid.c'
- fi
- if test -f 'header.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'header.c'\"
- else
- echo shar: Extracting \"'header.c'\" \(4796 characters\)
- sed "s/^X//" >'header.c' <<'END_OF_FILE'
- X/* $Header: header.c,v 2.2 89/06/09 13:08:07 network Exp $
- X *
- X * A program to parse RFC 822 mail/news headers.
- X *
- X * usage: header [-c] [-n] [-f field] ... files
- X *
- X * Default action is to print entire header. If one or more -f options
- X * are given, only the specified fields are printed. The field names are
- X * not printed unless -n is specified. Field name comparisons are case
- X * insensitive unless -c is specified.
- X *
- X * Output lines are preceeded by the filename if more than one file is
- X * specified.
- X *
- X * This program is intended for use in delivery files, to extract multi-
- X * line header fields.
- X *
- X * $Log: header.c,v $
- X * Revision 2.2 89/06/09 13:08:07 network
- X * Adapt to BSD quirks.
- X *
- X * Revision 2.1 89/06/09 12:25:29 network
- X * Update RCS revisions.
- X *
- X * Revision 1.5 89/06/09 12:23:51 network
- X * Baseline for 2.0 release.
- X *
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X/*
- X * Manifest constants
- X */
- X
- X#define TRUE 1
- X#define FALSE 0
- X
- X/*
- X * Other useful macros.
- X */
- X
- X#define GETSIZE(buf) (sizeof(buf) - 1)
- X
- X#define ISFROM(p) ((p)[0] == 'F' && (p)[1] == 'r' && (p)[2] == 'o' \
- X && (p)[3] == 'm' && (p)[4] == ' ')
- X
- X/*
- X * External data.
- X */
- X
- X/* Variables set by getopt() [blech] */
- X
- Xextern int optind, opterr;
- Xextern char *optarg;
- X
- X/*
- X * Library functions.
- X */
- X
- Xextern char *malloc();
- Xextern char *realloc();
- Xextern void free();
- X
- X/*
- X * Global data
- X */
- X
- Xint field_count = 0;
- Xint field_alloc = 0;
- Xchar **field_names = NULL;
- X
- Xint nocasematch = TRUE; /* ignore case in header matches */
- Xint printnames = FALSE; /* print field names with data */
- X
- X/*----------------------------------------------------------------------
- X * The Program.
- X */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X int c, errors;
- X
- X field_alloc = 8;
- X field_names = (char **) malloc(field_alloc * sizeof(char **));
- X if (field_names == NULL)
- X nomem();
- X
- X errors = FALSE;
- X while ((c = getopt(argc, argv, "cnf:")) != EOF)
- X {
- X switch (c)
- X {
- X case 'c':
- X nocasematch = FALSE;
- X break;
- X case 'n':
- X printnames = TRUE;
- X break;
- X case 'f':
- X if (field_count >= field_alloc)
- X {
- X field_alloc *= 2;
- X field_names =
- X (char **) realloc((char *)field_names,
- X field_alloc * sizeof(char **));
- X if (field_names == NULL)
- X nomem();
- X }
- X field_names[field_count++] = optarg;
- X break;
- X default:
- X errors = TRUE;
- X break;
- X }
- X }
- X
- X if (errors)
- X usage();
- X
- X if (optind == argc)
- X header(stdin, (char *)NULL);
- X else
- X {
- X FILE *fp;
- X int a, filenames;
- X
- X filenames = ((argc - optind) > 1);
- X for (a = optind; a < argc; ++a)
- X {
- X if ((fp = fopen(argv[a], "r")) == NULL)
- X {
- X errors = TRUE;
- X perror(argv[a]);
- X continue;
- X }
- X
- X header(fp, (filenames ? argv[a] : (char *)NULL));
- X fclose(fp);
- X }
- X }
- X
- X exit(errors ? 1 : 0);
- X}
- X
- Xusage()
- X{
- X fprintf(stderr, "usage: header [-c] [-f fieldname] ... files\n");
- X exit(1);
- X}
- X
- Xnomem()
- X{
- X fprintf(stderr, "header: out of memory\n");
- X exit(1);
- X}
- X
- Xheader(fp, filename)
- XFILE *fp;
- Xchar *filename;
- X{
- X char buf[1024];
- X
- X if (fgets(buf, GETSIZE(buf), fp) == NULL)
- X return;
- X
- X /* Ignore From_ line(s). */
- X
- X while (ISFROM(buf) || buf[0] == '>')
- X {
- X if (fgets(buf, GETSIZE(buf), fp) == NULL)
- X return;
- X }
- X
- X while (buf[0] != '\n')
- X {
- X char *p;
- X int print_this;
- X
- X p = buf;
- X while (isupper(*p) || islower(*p) || isdigit(*p) || *p == '-')
- X ++p;
- X if (p == buf || *p != ':')
- X break;
- X print_this = field(buf, p - buf);
- X if (print_this)
- X {
- X if (filename)
- X {
- X fputs(filename, stdout);
- X putc(':', stdout);
- X }
- X ++p;
- X if (*p == ' ' || *p == '\t')
- X ++p;
- X if (field_count == 0 || printnames)
- X fputs(buf, stdout);
- X else
- X fputs(p, stdout);
- X }
- X
- X /* get the next input line */
- X if (fgets(buf, GETSIZE(buf), fp) == NULL)
- X break;
- X
- X /* deal with continuation lines */
- X while (buf[0] == ' ' || buf[0] == '\t')
- X {
- X if (print_this)
- X {
- X if (filename)
- X {
- X fputs(filename, stdout);
- X putc(':', stdout);
- X }
- X fputs(buf, stdout);
- X }
- X
- X if (fgets(buf, GETSIZE(buf), fp) == NULL)
- X {
- X buf[0] = '\n';
- X break;
- X }
- X }
- X }
- X}
- X
- Xint
- Xfield(s, n)
- Xchar *s;
- Xint n;
- X{
- X int i;
- X
- X if (field_count == 0)
- X return TRUE;
- X
- X for (i = 0; i < field_count; ++i)
- X {
- X char *f = field_names[i];
- X
- X if (strlen(f) == n)
- X {
- X if (nocasematch)
- X {
- X if (ci_strncmp(f, s, n) == 0)
- X return TRUE;
- X }
- X else
- X {
- X if (strncmp(f, s, n) == 0)
- X return TRUE;
- X }
- X }
- X }
- X
- X return FALSE;
- X}
- X
- Xint
- Xci_strncmp(s, t, n)
- Xchar *s, *t;
- Xint n;
- X{
- X char c, d;
- X
- X while (n-- > 0)
- X {
- X c = *s++;
- X d = *t++;
- X if ((c == 0) && (d == 0))
- X break;
- X if (isupper(c))
- X c = tolower(c);
- X if (isupper(d))
- X d = tolower(d);
- X if (c > d)
- X return 1;
- X if (c < d)
- X return -1;
- X }
- X
- X return 0;
- X}
- END_OF_FILE
- if test 4796 -ne `wc -c <'header.c'`; then
- echo shar: \"'header.c'\" unpacked with wrong size!
- fi
- # end of 'header.c'
- fi
- if test -f 'getopt.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'getopt.c'\"
- else
- echo shar: Extracting \"'getopt.c'\" \(1719 characters\)
- sed "s/^X//" >'getopt.c' <<'END_OF_FILE'
- X/* $Header: getopt.c,v 2.1 89/06/09 12:25:28 network Exp $
- X *
- X * A version of the public-domain getopt() function, as found
- X * in the SVID and fine Unix manuals everywhere.
- X *
- X * $Log: getopt.c,v $
- X * Revision 2.1 89/06/09 12:25:28 network
- X * Update RCS revisions.
- X *
- X * Revision 1.4 89/06/09 12:23:50 network
- X * Baseline for 2.0 release.
- X *
- X */
- X
- X#include <stdio.h>
- X#include "config.h"
- X#include "misc.h"
- X
- X/*----------------------------------------------------------------------
- X * Get command line options.
- X * This is essentially the public domain version, just reformatted to
- X * match the rest of the deliver program.
- X */
- X
- X#ifndef HAS_GETOPT
- X
- Xint opterr = 1;
- Xint optind = 1;
- Xint optopt = 0;
- Xchar *optarg = NULL;
- X
- X#define ERR(what,c) \
- X if (!opterr) {} else fprintf(stderr,"%s: %s -- %c\n", argv[0], what, c);
- X
- Xint
- Xgetopt(argc, argv, opts)
- Xint argc;
- Xchar **argv;
- Xchar *opts;
- X{
- X static int sp = 1;
- X int c;
- X char *cp;
- X
- X if (sp == 1)
- X {
- X if (optind >= argc
- X || argv[optind][0] != '-' || argv[optind][1] == '\0')
- X return EOF;
- X
- X if (strcmp(argv[optind], "--") == NULL)
- X {
- X optind++;
- X return EOF;
- X }
- X }
- X
- X optopt = c = argv[optind][sp];
- X
- X if (c == ':' || (cp = strchr(opts, c)) == NULL)
- X {
- X ERR("illegal option", c);
- X if (argv[optind][++sp] == '\0')
- X {
- X optind++;
- X sp = 1;
- X }
- X return '?';
- X }
- X
- X if (*++cp == ':')
- X {
- X if (argv[optind][sp + 1] != '\0')
- X optarg = &argv[optind++][sp + 1];
- X else if (++optind >= argc)
- X {
- X ERR("option requires an argument", c);
- X sp = 1;
- X return '?';
- X }
- X else
- X optarg = argv[optind++];
- X
- X sp = 1;
- X }
- X else
- X {
- X if (argv[optind][++sp] == '\0')
- X {
- X sp = 1;
- X optind++;
- X }
- X
- X optarg = NULL;
- X }
- X
- X return c;
- X}
- X
- X#endif /* !HAS_GETOPT */
- END_OF_FILE
- if test 1719 -ne `wc -c <'getopt.c'`; then
- echo shar: \"'getopt.c'\" unpacked with wrong size!
- fi
- # end of 'getopt.c'
- fi
- if test ! -d 'samples' ; then
- echo shar: Creating directory \"'samples'\"
- mkdir 'samples'
- fi
- if test -f 'samples/README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'samples/README'\"
- else
- echo shar: Extracting \"'samples/README'\" \(229 characters\)
- sed "s/^X//" >'samples/README' <<'END_OF_FILE'
- XREADME for samples.
- X
- XThese sample delivery file are provides for your edification and amusement.
- XI've actually tested u-chip and u-vacation; the other samples are just off
- Xthe top of my head. Use at your own risk, and all that.
- END_OF_FILE
- if test 229 -ne `wc -c <'samples/README'`; then
- echo shar: \"'samples/README'\" unpacked with wrong size!
- fi
- # end of 'samples/README'
- fi
- if test -f 'samples/p-aliases' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'samples/p-aliases'\"
- else
- echo shar: Extracting \"'samples/p-aliases'\" \(445 characters\)
- sed "s/^X//" >'samples/p-aliases' <<'END_OF_FILE'
- X: p-aliases
- X# A sample post-user deliver file.
- X#
- X# This post-user delivery file provides system-wide aliases that are
- X# processed after user delivery files have had their say.
- X
- Xfor u
- Xdo
- X case $u in
- X root) echo buoc ;; # Big User On Computer :-)
- X uucp) echo buoc ;;
- X postmaster) echo buoc ;;
- X bug-alias) echo user1; echo user2 ;; # Both users get each message
- X *) echo $u ;;
- X esac
- Xdone
- END_OF_FILE
- if test 445 -ne `wc -c <'samples/p-aliases'`; then
- echo shar: \"'samples/p-aliases'\" unpacked with wrong size!
- fi
- # end of 'samples/p-aliases'
- fi
- if test -f 'samples/s-aliases' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'samples/s-aliases'\"
- else
- echo shar: Extracting \"'samples/s-aliases'\" \(653 characters\)
- sed "s/^X//" >'samples/s-aliases' <<'END_OF_FILE'
- X: s-aliases
- X# A sample system delivery file.
- X#
- X# While Joe is gone, send problem reports to Fred.
- X# Note that since user delivery files are processed after this one,
- X# Fred's user delivery file may direct all such mail back to joe
- X# if Fred wants to be difficult. :-)
- X# Note that a better solution is to use a bug report alias,
- X# but this method demonstrates variable delivery based
- X# on message headers.
- X
- XSUBJECT=`header -f subject $HEADER | tr '[A-Z]' '[a-z]'`
- X
- Xfor u
- Xdo
- X case $u in
- X joe) case $SUBJECT in
- X *bug*|*problem*) echo fred ;;
- X *) echo joe ;;
- X esac ;;
- X *) echo $u ;;
- X esac
- Xdone
- END_OF_FILE
- if test 653 -ne `wc -c <'samples/s-aliases'`; then
- echo shar: \"'samples/s-aliases'\" unpacked with wrong size!
- fi
- # end of 'samples/s-aliases'
- fi
- if test -f 'samples/u-chip' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'samples/u-chip'\"
- else
- echo shar: Extracting \"'samples/u-chip'\" \(247 characters\)
- sed "s/^X//" >'samples/u-chip' <<'END_OF_FILE'
- X: u-chip
- X# Chip's user delivery file.
- X
- Xuser="$1"
- XTO=`header -f To -f CC $HEADER`
- X
- Xcase "$SENDER" in
- X*zardoz*!sec*) echo $user:mbox.sec; exit ;;
- Xesac
- X
- Xcase "$TO" in
- X*ietf*|*ineng*) echo $user:mbox.ietf; exit ;;
- Xesac
- X
- X# Default case
- Xecho $user
- END_OF_FILE
- if test 247 -ne `wc -c <'samples/u-chip'`; then
- echo shar: \"'samples/u-chip'\" unpacked with wrong size!
- fi
- # end of 'samples/u-chip'
- fi
- if test -f 'samples/u-vacation' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'samples/u-vacation'\"
- else
- echo shar: Extracting \"'samples/u-vacation'\" \(1033 characters\)
- sed "s/^X//" >'samples/u-vacation' <<'END_OF_FILE'
- X: u-vacation
- X# A user delivery file for when you're on vacation.
- X#
- X# The ALREADY file remembers who you've already mailed vacation messages to.
- X# The BEBACK string is the date you will return.
- X
- XALREADY=vacation.list
- XBEBACK="on July 4, 1776"
- X
- Xecho "$1" # Keep the mail!
- X
- Xif grep '^'${SENDER}'$' $ALREADY >/dev/null 2>/dev/null
- Xthen
- X exit 0 # We already notified this person; reject
- Xfi
- X
- Xcase $SENDER in
- X*uucp) exit 0 ;; # Not a human; reject
- X*daemon) exit 0 ;; # Not a human; reject
- X*DAEMON) exit 0 ;; # Not a human; reject
- X*!*) ;;
- X*@*) ;;
- X## *) exit 0 ;; # Local user; reject (maybe)
- Xesac
- X
- X# Remember this person
- Xecho $SENDER >>$ALREADY
- X
- X# Send the vacation message
- XSUBJECT=`header -f subject $HEADER`
- Xmail -s "I'm on vacation" $SENDER <<!EOF!
- XYour message to me on the subject
- X "$SUBJECT"
- Xhas been delivered. However, I am on vacation, so I have not yet
- Xread your message. I will be back $BEBACK.
- X
- XThis is the only such message you will receive.
- X
- XThank you.
- X!EOF!
- END_OF_FILE
- if test 1033 -ne `wc -c <'samples/u-vacation'`; then
- echo shar: \"'samples/u-vacation'\" unpacked with wrong size!
- fi
- # end of 'samples/u-vacation'
- fi
- echo shar: End of shell archive.
- exit 0
-
-
-